﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace ProcessFile
{
    public class Stk4PIC2581
    {
        public XDocument _rootTemp = new XDocument();//data of xml
        public string[] _lines;
          XNamespace _namespace;
        public Stk4PIC2581(string filePathStk, string filePathTemp)
        {
            _rootTemp = XDocument.Load(filePathTemp);
            _lines = Common.ReadFileText(filePathStk);
            _namespace = _rootTemp.Root.Name.Namespace;
            
        }
        public decimal GetUnitConvert
        {
            get {
                return 1000;
            }
        }
     public string Convert4Xml
     {
         get {
             string convertText = "";
             IEnumerable<XElement> stackupLayers=StackupLayers;
             int delectricCount=0;
             for (int i = 0; i < _lines.Length; i++)
             {
                 string[] item = _lines[i].Split(Common.SplipChar);
                
                 if (item.Length>11)
                 {
                     if (!Common.CheckIsDielectric(_lines[i]))
                     {
                         XElement elementTemp = stackupLayers.Where(x => x.Attribute("materialType").Value == "COPPER").FirstOrDefault();
                         convertText += StkLine4XmlLayer(_lines[i], elementTemp) + '\n';
                     }
                     else
                     {
                         delectricCount++;
                         
                          if (i == TopSolder || i == BottomSolder)
                          {
                              XElement elementTemp = stackupLayers.Where(x => x.Attribute("materialType").Value != "COPPER" && x.Attribute("materialType").Value != "AIR").FirstOrDefault();
                              convertText += StkLine4XmlSolderMask(_lines[i], elementTemp, delectricCount) + '\n';
                          }
                          else
                          {
                              XElement elementTemp = stackupLayers.Where(x => x.Attribute("materialType").Value != "COPPER" && x.Attribute("materialType").Value != "AIR").ToList()[1];
                              convertText += StkLine4XmlDelectric(_lines[i], elementTemp, delectricCount)+'\n';
                          }
                     }
                 }
             }
             return   convertText;
         }

     }
     public IEnumerable<XElement> StackupLayers
     {
         get
         {
             return _rootTemp.Descendants(_namespace + Common.StackupLayerElement);
         }
     }
       
        public string StkLine4XmlLayer(string stkLine,XElement xmlElement)
        {
            string[] item=stkLine.Split(Common.SplipChar);
            string layerName=item[Common.LayerNameIndex];
            string thinkness=item[Common.CopperThicknessIndex];
            string zo=item[Common.ZoIndex];
            string zdiff=item[Common.ZdiffIndex];
             string traceWidth=item[Common.TraceWithdIndex];
            string traceClearance=item[Common.TraceWithdIndex];
            string zdbs=item[Common.ZdbsIndex];
            //replace data
             xmlElement.Attribute(Common.layerOrGroupRefAttribute).Value=layerName;
             xmlElement.Attribute(Common.thicknessAttribute).Value=thinkness;
            //node SINGLE_END  replae  value  zo
            var element =xmlElement.Elements(_namespace+Common.NonstandardAttribute).Where(x=>x.Attribute("name").Value=="LAYER_IMPEDANCE"&& x.Attribute("transmission").Value=="SINGLE_ENDED" && x.Attribute("type").Value=="IMPEDANCE").FirstOrDefault();
            if (element!=null)
                element.Attribute("value").Value=zo;
            //node LINEWIDTH  replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "SINGLE_ENDED" && x.Attribute("type").Value == "LINEWIDTH").FirstOrDefault();
            if (element!=null)
                element.Attribute("value").Value=traceWidth;
            //node EDGE_COUPLED   replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "EDGE_COUPLED" && x.Attribute("type").Value == "IMPEDANCE").FirstOrDefault();
            if (element!=null)
                element.Attribute("value").Value=zdiff;
               //node LINEWIDTH   replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "EDGE_COUPLED" && x.Attribute("type").Value == "LINEWIDTH").FirstOrDefault();
            if (element!=null)
                element.Attribute("value").Value=traceWidth;
              //node SPACING    replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "EDGE_COUPLED" && x.Attribute("type").Value == "SPACING").FirstOrDefault();
            if (element!=null)
                element.Attribute("value").Value=traceWidth;

	         if (zdbs!="")
	        {
                XElement elementNew = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "SINGLE_ENDED" && x.Attribute("type").Value == "IMPEDANCE").FirstOrDefault();
                XElement newZdbs = XElement.Parse(elementNew.ToString());
                newZdbs.Attribute("transmission").Value = "BROADSIDE_COUPLED";
                newZdbs.Attribute("value").Value = zdbs;
                xmlElement.Add(newZdbs);
                elementNew = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "SINGLE_ENDED" && x.Attribute("type").Value == "LINEWIDTH").FirstOrDefault();
                XElement newTraceWidth = XElement.Parse(elementNew.ToString());
                newTraceWidth.Attribute("transmission").Value = "BROADSIDE_COUPLED";
                xmlElement.Add(newTraceWidth);
                elementNew = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_IMPEDANCE" && x.Attribute("transmission").Value == "EDGE_COUPLED" && x.Attribute("type").Value == "SPACING").FirstOrDefault();
                XElement newSpace = XElement.Parse(elementNew.ToString());
                newSpace.Attribute("transmission").Value = "BROADSIDE_COUPLED";
                xmlElement.Add(newSpace);
	        }
             return xmlElement.ToString().Replace("xmlns=\""+_namespace+"\n","");
        }
        public string GetDf(string note)
        {
            int indexStart = note.IndexOf("Df=");
            if (indexStart<0)
            {
                return "";
            }
            int lastIndex = note.LastIndexOf(";");
            if (lastIndex<indexStart)
            {
                lastIndex = note.Length - 1;
            }
            return note.Substring(indexStart + 3, lastIndex - indexStart - 2).Trim();
        }
        public string GetTg(string note)
        {
            int indexStart = note.IndexOf("Tg=");
            if (indexStart < 0)
            {
                return "";
            }
            int lastIndex = note.IndexOf("C");
            if (lastIndex < 0)
            {
                return "";
            }
            return note.Substring(indexStart + 3, lastIndex - indexStart - 3).Trim();
        }
        public string GetRc(string note)
        {
            int indexStart = note.IndexOf("Rc=");
            if (indexStart < 0)
            {
                return "";
            }
            int lastIndex = note.Substring(indexStart).IndexOf("%");
            if (lastIndex < 0)
            {
                return "";
            }
            return note.Substring(indexStart + 3, lastIndex -3 ).Trim();
        }
        public string GetGLASS_STYLE(string note)
        {
            string[] item = note.Split(';');
            if (item.Length>1)
            {
                return item[1].Trim();
            }
            return "";
        }
        public string StkLine4XmlDelectric(string stkLine, XElement xmlElement,int count)
        {
            string[] item = stkLine.Split(Common.SplipChar);
            string layerName = "DIELECTRIC" + count;
            string materialType = item[Common.MaterialTypeIndex];
            string delectricContains = item[Common.DielectricConstantIndex];
            string note = item[Common.NoteIndex];
            string thinkness = item[Common.DielectricThinknessIndex];
            string zo = item[Common.ZoIndex];
            string zdiff = item[Common.ZdiffIndex];
            string traceWidth = item[Common.TraceWithdIndex];
            string traceClearance = item[Common.TraceWithdIndex];
            string zdbs = item[Common.ZdbsIndex];
            
            //get df
            string df = GetDf(note);
            string tg = GetTg(note);
            string rc = GetRc(materialType);
            string gs = GetGLASS_STYLE(materialType);
            if (df=="")
            {
                df = "0";
            }
            if (tg == "")
            {
                tg = "0";
            }
            if (rc == "")
            {
                rc = "0";
            }
            if (gs == "")
            {
                gs = "0";
            }
            //replace data
            xmlElement.Attribute(Common.layerOrGroupRefAttribute).Value = layerName;
            xmlElement.Attribute(Common.materialTypeAttribute).Value = materialType;
            xmlElement.Attribute(Common.thicknessAttribute).Value = thinkness;
            //node SINGLE_END  replae  value  zo
            var element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_DIELECTRIC_CONSTANT").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = delectricContains;
            //node LINEWIDTH  replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_LOSS_TANGENT").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = df;
            //node EDGE_COUPLED   replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_RESIN_CONTENT").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = rc;
            //node LINEWIDTH   replaee value  traceWidth
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_GLASS_STYLE").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = gs;
            element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "MINIMIUM_TG").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = tg;
            return xmlElement.ToString().Replace("xmlns=\"" + _namespace + "\n","");
        }
        public string StkLine4XmlSolderMask(string stkLine, XElement xmlElement, int count)
        {
            string[] item = stkLine.Split(Common.SplipChar);
            string layerName = "DIELECTRIC" + count;
            string materialType = item[Common.MaterialTypeIndex];
            string delectricContains = item[Common.DielectricConstantIndex];
            string note = item[Common.NoteIndex];
            string thinkness = item[Common.DielectricThinknessIndex];
            //get df
          
            //replace data
            xmlElement.Attribute(Common.layerOrGroupRefAttribute).Value = layerName;
            xmlElement.Attribute(Common.materialTypeAttribute).Value = materialType;
            xmlElement.Attribute(Common.thicknessAttribute).Value = thinkness;
            //node SINGLE_END  replae  value  zo
            var element = xmlElement.Elements(_namespace + Common.NonstandardAttribute).Where(x => x.Attribute("name").Value == "LAYER_DIELECTRIC_CONSTANT").FirstOrDefault();
            if (element != null)
                element.Attribute("value").Value = delectricContains;
            return xmlElement.ToString().Replace("xmlns=\"" + _namespace + "\n", "");
            //node LINEWIDTH  replaee value  traceWidth
        }
        public int UnitLine
        {
            get
            {
                for (int i = 0; i < _lines.Length; i++)
                {
                    if (_lines[i].Trim() == "um" || _lines[i].Trim() == "mil")
                    {
                        return i;
                    }
                }
                return -1;
            }
        }
        public int TopSolder
        {
            get { return 0; }

        }
        public int TopLayer
        {
            get
            {
                for (int i = 0; i < _lines.Length; i++)
                {
                    if (Common.CheckLayer(_lines[i]))
                    {
                        return i;
                    }
                }
                return -1;
            }

        }
        public int BottomLayer
        {
            get
            {
                for (int i = UnitLine; i > 0; i--)
                {
                    if (Common.CheckLayer(_lines[i]))
                    {
                        return i;
                    }
                }
                return -1;
            }

        }
        public int BottomSolder
        {
            get
            {
                for (int i = UnitLine; i > 0; i--)
                {
                    if (Common.CheckIsDielectric(_lines[i]))
                    {
                        return i;
                    }
                }
                return -1;
            }

        }
   
    }
}
